<?php
/**
 * --------------------------------------------------------------------
 * MCore精简框架
 * 作者：阿枫，QQ：52037872，Email：support@mdeve.com
 * --------------------------------------------------------------------
 *
 * SVN revision information:
 * @version $Revision: 1 $:
 * @author  $Author: zy $:
 * @date      $Date: 2017-03-10 21:12:21 +0800 (星期五, 10 三月 2017) $:
 */

class _EncryptClass extends __basic_def{

    private $_iv = '';
    private $_secret = '';

    function __construct(){
        global $_M;

        $this->_iv = substr($_M->cfg["SECURE_KEY3"].'0000000000000000', 0,16);
        $this->_secret = hash('md5', $_M->cfg["SECURE_KEY3"],true);
    }

    function aes_decode($secretData){
        return openssl_decrypt(urldecode($secretData),'aes-128-cbc',$this->_secret,false,$this->_iv);
    }

    function aes_encode($data){
        return urlencode(openssl_encrypt($data,'aes-128-cbc',$this->_secret,false,$this->_iv));
    }

    /**
     * 加密
     *
     * @param string $str
     */
    function EncodeZ($str, $key1 = "", $key2 = ""){
        global $config;
        $b = array();
        $c = array();
        $s = '';
        if (strlen($key1) != 16) $key1 = $config['SECURE_KEY1'];
        if (strlen($key2) != 16) $key2 = $config['SECURE_KEY2'];
        if (function_exists('gzcompress'))
            $str = gzcompress($str);
        for ($i = 0; $i < strlen($str); $i++) {
            $s = ord(substr($str, $i, 1));
            $y = $s % 16;
            $n = intval($s / 16);
            $b [] = substr($key2, $y, 1);
            $c [] = substr($key1, $n, 1);
        }
        $m = substr(md5(md5(implode('', $c)) . implode('', $b)), 3, 12);
        return implode('', $b) . implode('', $c) . $m;
    }

    /**
     * 解密
     *
     * @param string $str
     * @return string
     */
    function DecodeZ($str, $key1 = "", $key2 = ""){
        global $config;
        if (strlen($key1) != 16) $key1 = $config['SECURE_KEY1'];
        if (strlen($key2) != 16) $key2 = $config['SECURE_KEY2'];
        $str = strtolower($str);
        $m = substr($str, strlen($str) - 12);
        $str = substr($str, 0, strlen($str) - 12);
        $s1 = substr($str, 0, strlen($str) / 2);
        $s2 = substr($str, strlen($str) / 2);
        if ($m != substr(md5(md5($s2) . $s1), 3, 12))
            return false;
        $ret = '';
        for ($i = 0; $i < strlen($s1); $i++) {
            $s3 = substr($s1, $i, 1);
            $s4 = substr($s2, $i, 1);
            $y = strpos($key2, $s3);
            $n = strpos($key1, $s4);
            $ret .= chr($n * 16 + $y);
        }
        if (function_exists('gzuncompress'))
            $ret = gzuncompress($ret);
        return $ret;
    }


    /**
     * 加密或减密cookie字符串
     * @param $string 要加密或减密的字符串
     * @param $operation 操作方式
     * @param $key 加密KEY，可选
     * @param $expiry 过期时间
     */
    function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
        global $config;
        $ckey_length = 4;
        $key = md5($key ? $key : $config['SECURE_KEY3']);
        $keya = md5(substr($key, 0, 16));
        $keyb = md5(substr($key, 16, 16));
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

        $cryptkey = $keya.md5($keya.$keyc);
        $key_length = strlen($cryptkey);

        $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 6, 16).$string;
        $string_length = strlen($string);

        $result = '';
        $box = range(0, 255);

        $rndkey = array();
        for($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }

        for($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }

        for($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }

        if($operation == 'DECODE') {
            if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 6, 16)) {
                return substr($result, 26);
            } else {
                return '';
            }
        } else {
            return $keyc.str_replace('=', '', base64_encode($result));
        }
    }

}